package cn.skyquant.quant4j.service.boot.model.fund;

import cn.skyquant.quant4j.api.fund.FundDTO;
import cn.skyquant.quant4j.sdk.enums.Status;
import cn.skyquant.quant4j.sdk.util.time.CalendarUtils;
import cn.skyquant.quant4j.sdk.util.time.Period;
import cn.skyquant.quant4j.service.boot.model.account.Account;
import cn.skyquant.quant4j.service.boot.model.order.AccountOrderHis;
import cn.skyquant.quant4j.service.boot.model.order.AccountOrderHisRepository;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class FundService {

    @Resource
    FundRepository fundRepository;

    @Resource
    FundHisRepository fundHisRepository;

    @Resource
    AccountOrderHisRepository accountOrderHisRepository;


    public List<FundDTO> findAllFund() {
        List<Fund> fundList = fundRepository.findByStatus(Status.A);
        List<FundDTO> fundDTOList = fundList.stream().map(x -> convert(x)).collect(Collectors.toList());
        return fundDTOList;
    }

    private FundDTO convert(Fund fund) {
        FundDTO fundDTO = new FundDTO();
        fundDTO.id = fund.id;
        fundDTO.name = fund.name;
        return fundDTO;
    }

    //查找基金历史交易记录
    public List<FundDaily> findDaily(Integer id,long time) {
        LinkedList<FundDaily> fundDailyList = new LinkedList<>();
        Optional<Fund> fundOptional = fundRepository.findById(id);
        if (fundOptional.isPresent()) {
            Fund fund = fundOptional.get();
            Account account = fund.account;
            List<FundHis> fundHisList = fundHisRepository.findByFund(fund);//历史入金
            if (!fundHisList.isEmpty()) {
                Date thedate = fundHisList.get(0).thedate;
                FundDaily fundDaily = new FundDaily();
                fundDaily.date = CalendarUtils.getFirstTime(thedate, Period.daily);
                fundDaily.basic = fundHisList.get(0).money;
                fundDaily.equity = fundDaily.basic;
                fundDaily.profit = 0;
                fundDaily.i = 0;
                fundDailyList.add(fundDaily);

                List<AccountOrderHis> orderHisList = accountOrderHisRepository.findByAccount(account);
                //
                while (thedate.getTime() < time) {
                    FundDaily last = fundDailyList.getLast();
                    FundDaily f = new FundDaily();
                    f.date = CalendarUtils.addDate(last.date,1);
                    f.basic = last.basic;
                    f.i = last.i+1;
                    long s0 = f.date.getTime();
                    long s1 = s0+86400000;
                    double basic = fundHisList.stream().filter(x->x.thedate.getTime() >= s0 && x.thedate.getTime()< s1).mapToDouble(x->x.money).sum();
                    f.basic += basic;
                    f.profit += orderHisList.stream().filter(x->x.closeTime !=null && x.closeTime.getTime() >= s0 && x.closeTime.getTime() < s1).mapToDouble(x->x.profit).sum();
                    f.equity = last.equity + f.profit + basic;
                    fundDailyList.add(f);
                    thedate = f.date;
                }
            }
        }
        return fundDailyList;
    }
}
